﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using VDataAdapter.BlockingQueue;

namespace VDataAdapter
{ 
    /// <summary>
    /// This class send objects to queue
    /// include a flag checker to check the sequence
    /// All data send to Vdata queue should use this class
    /// all Send method is atomic
    /// </summary>
    class VdataCommunicator
    {
        public VdataCommunicator(DataSource dataSource, CommunicationDataQueue queue)        
        {
            _queue = queue;

            _dataSource = dataSource;
            
            MessageBuilder msgBuilder = new MessageBuilder();
            _builder = new ProtocolMessageBuilder(msgBuilder, _dataSource);
            _checker = new VdataFlagChecker();
        }

        public void UpdateBasePrices(IDictionary<string, PriceLibrary.PriceService.StockBase> basePrices)
        {
            _builder.UpdateBasePrices(basePrices);
        }

        /// <summary>
        /// send 1 transaction, if it is already in the DataSource then send the new along with the old
        /// it should be blocking too since many thread may want to update DataSource
        /// </summary>
        /// <param name="transaction"></param>        
        public void SendTransactionPutThrough(PriceLibrary.PriceService.Transaction transaction)
        {
            throw new NotImplementedException();
        }

        public void SendTransaction(PriceLibrary.ChartService.Transaction transaction)
        {
            lock (this)
            {
                string msg;
                // if DataSource already contain this Transaction, send new transaction along with the old
                msg = _builder.BuildMessageTransaction(transaction);

                // send the message
                SendToQueue(msg, _queue);
            }
        }

        public void SendFlag(MessageFlagSequeue flag)
        {
            lock (this)
            {
                string flagMsg = VDataFlag.GetFlag(flag);
                _checker.CheckFlag(flagMsg);
                SendToQueue(flagMsg, _queue);
            }
        }

        public void SendMarketInfo(int key, PriceLibrary.PriceService.MarketInfo marketInfo)
        {
            lock (this)
            {
                string msg;
                msg = _builder.BuildMessageMarketInfo(key, marketInfo);

                SendToQueue(msg, _queue);
            }
        }

        public void SendStock(string key, PriceLibrary.PriceService.StockInfoDyns dynamicInfo)
        {
            lock (this)
            {
                string msg;
                msg = _builder.BuildMessageStockInfo(key, dynamicInfo);

                SendToQueue(msg, _queue);
            }
        }

        #region Private functions & properties

        protected DataSource _dataSource;

        protected ProtocolMessageBuilder _builder;

        protected CommunicationDataQueue _queue;

        protected VdataFlagChecker _checker;

        protected void SendToQueue(string msg, CommunicationDataQueue queue)
        {
            MessageObject objData = new MessageObject(msg);
            DataQueue objQueue = new DataQueue();
            queue.put(new CommunicationData(objData, objQueue));
        }

        #endregion


        //private string BuildMessageTransaction(PriceLibrary.ChartService.Transaction transaction, IDictionary<string, PriceLibrary.ChartService.Transaction> transactions)
        //{
        //    string msg;
        //    if (IsOldTransactionExisted(transaction))
        //    {
        //        msg = _messageBuilder.BuildMessageTransaction(transaction, transactions[transaction.Symbol]);
        //    }
        //    else
        //    {
        //        msg = _messageBuilder.BuildMessageTransaction(transaction, transaction);
        //    }
        //    return msg;
        //}

        //private bool IsOldTransactionExisted(PriceLibrary.ChartService.Transaction transaction)
        //{
        //    return _dataSource.Transactions.ContainsKey(transaction.Symbol);
        //}


    }
}
